package com.hncc.kumao.quartz;

import java.io.File;
import java.util.Date;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import com.hncc.kumao.biz.INetdiskAccessTokenBiz;
import com.hncc.kumao.biz.IOfflineDownloadTaskBiz;
import com.hncc.kumao.entity.NetdiskAccessToken;
import com.hncc.kumao.entity.OfflineDownloadTask;
import com.hncc.kumao.entity.OfflineDownloadTaskInfo;
import com.hncc.kumao.entity.OfflineDownloadTaskWait;
import com.hncc.kumao.exception.KumaoNetdiskFileNotFoundException;
import com.hncc.kumao.tool.DownloadFileTool;
import com.hncc.kumao.util.ConstValue;
import com.hncc.kumao.util.MyFileUtils;
import com.hncc.kumao.util.OfflineDownloadUtils;

public class NormalDownloadTaskJob {
    
    private static ExecutorService executor = Executors.newFixedThreadPool(5);
    private IOfflineDownloadTaskBiz offlineDownloadTaskBiz;
    private INetdiskAccessTokenBiz netdiskAccessTokenBiz;
    private DownloadFileTool downloadFileTool;
    
    public void doTask() {
        
        //判断任务列表数量,和当前正在下载的任务数量有没有大于并行限制数
        while(OfflineDownloadUtils.getNormalQueueNumber() > 0 && 
                (OfflineDownloadUtils.getNormalTaskNumber() < 
                OfflineDownloadUtils.getNormalParallelNumber())) {
            
            System.out.println("可以下载任务");
            //获取并移除正常队列顶部任务id
            String topTaskId = OfflineDownloadUtils.getNormalQueueTopTaskId();
            //将这个id添加到正在进行中的任务
            OfflineDownloadUtils.addNormalTask(topTaskId);
            //调用线程池进行下载
            executor.submit(new DoDownloadTask(topTaskId));
        }
    }

    private class DoDownloadTask implements Runnable {

        private String taskId;
        private boolean success;//是否下载成功
        private boolean notFound;//文件不存在
        public DoDownloadTask(String taskId) {
            this.taskId = taskId;
        }
        
        @Override
        public void run() {
            System.out.println("正在下载ID为: " + taskId + "的任务");
            success = true;
            notFound = false;
            //从数据库中获取离线下载任务信息和网盘信息
            OfflineDownloadTask offlineDownloadTask = offlineDownloadTaskBiz.get(taskId);
            //TODO 测试外键
            //NetdiskAccessToken netdiskAccessToken = netdiskAccessTokenBiz.get(offlineDownloadTask.getTargetNetdiskAccessTokenId());
            NetdiskAccessToken netdiskAccessToken = offlineDownloadTask.getNetdiskAccessToken();
            //设置更新相关信息
            if(offlineDownloadTask.getState() == ConstValue.OD_TASK_STATE_NEW) {
                offlineDownloadTask.setState(ConstValue.OD_TASK_STATE_GOING);
                offlineDownloadTask.setStartTime(new Date());
            }
            String fileName = new File(offlineDownloadTask.getFileUri()).getName();
            String serverFileUri = "/" + ConstValue.DOWNLOAD_DIR_NAME + "/" + offlineDownloadTask.getUserId() + 
                    "/" + offlineDownloadTask.getId() + MyFileUtils.getFileSuffix(fileName);
            String fileSavePath = ConstValue.BASE_RES_PATH + serverFileUri;
            offlineDownloadTask.setFileSavePath(fileSavePath);
            //向数据库更新
            offlineDownloadTaskBiz.update(offlineDownloadTask);
            //同时更新redis中信息
            OfflineDownloadTaskInfo taskInfo = OfflineDownloadUtils.getTaskProgressRate(taskId);
            taskInfo.setStartTime(offlineDownloadTask.getStartTime());
            taskInfo.setState(offlineDownloadTask.getState());
            OfflineDownloadUtils.setTaskProgressRate(taskInfo);
            //根据网盘类型调用对应的下载类
            try {
                switch (netdiskAccessToken.getNetdiskType()) {
                case ConstValue.NETDISK_TYPE_BAIDU:
                    downloadFileTool.downloadBaiDuFile(offlineDownloadTask, netdiskAccessToken);
                    break;
                case ConstValue.NETDISK_TYPE_JIANGUOYUN:
                    downloadFileTool.downloadJianGuoYunFile(offlineDownloadTask, netdiskAccessToken);
                    break;
                case ConstValue.NETDISK_TYPE_FTP:
                    downloadFileTool.downloadFTPFile(offlineDownloadTask, netdiskAccessToken);
                    break;
                case ConstValue.NETDISK_TYPE_SEAFILE:
                    downloadFileTool.downloadSeafileFile(offlineDownloadTask, netdiskAccessToken);
                    break;
                case ConstValue.NETDISK_TYPE_SMB:
                    downloadFileTool.downloadSMBFile(offlineDownloadTask, netdiskAccessToken);
                    break;
                default:
                    break;
                }
            } catch (KumaoNetdiskFileNotFoundException notFoundException) {
                //文件未找到
                success = false;
                notFound = true;
                notFoundException.printStackTrace();
            } catch (Exception e) {
                //下载过程中出错
                success = false;
                e.printStackTrace();
            }
            //执行完成，从正在进行中的任务队列中删除该任务
            OfflineDownloadUtils.removeNormalTask(taskId);
            //重新从数据库中获取信息
            offlineDownloadTask = offlineDownloadTaskBiz.get(taskId);
            //判断是否已删除或取消该任务
            if(offlineDownloadTask.getState() == ConstValue.OD_TASK_STATE_DELETE 
                    || offlineDownloadTask.getState() == ConstValue.OD_TASK_STATE_CANCEL) {
                //已删除该任务,删除本地文件
                String savePath = offlineDownloadTask.getFileSavePath();
                if(savePath != null && savePath.trim().length() > 0) {
                    File file = new File(savePath);
                    if(file.exists()) {
                        file.delete();
                        File parentFile = file.getParentFile();
                        parentFile.delete();
                    }
                    offlineDownloadTask.setFileSavePath(null);
                }
                //删除redis中的数据
                OfflineDownloadUtils.removeTaskProgressRate(offlineDownloadTask.getId());
            } else {
                //判断是否成功
                if(success) {
                    //下载成功,设置相关信息
                    offlineDownloadTask = offlineDownloadTaskBiz.get(taskId);
                    if(offlineDownloadTask.getState() == ConstValue.OD_TASK_STATE_GOING) {
                        offlineDownloadTask.setState(ConstValue.OD_TASK_STATE_SUCCESS);
                        offlineDownloadTask.setEndTime(new Date());
                        String fileDownloadUri = ConstValue.BASE_RES_URL + serverFileUri;
                        offlineDownloadTask.setFileDownloadUrl(fileDownloadUri);
                    }
                    taskInfo = OfflineDownloadUtils.getTaskProgressRate(taskId);
                    taskInfo.setState(offlineDownloadTask.getState());
                    taskInfo.setEndTime(offlineDownloadTask.getEndTime());
                } else {
                    System.out.println("下载出错了");
                    if(notFound) {
                        //直接失败
                        System.out.println("没找到文件");
                        offlineDownloadTask.setState(ConstValue.OD_TASK_STATE_FAIL);
                        taskInfo = OfflineDownloadUtils.getTaskProgressRate(taskId);
                        taskInfo.setState(offlineDownloadTask.getState());
                    } else {
                        //下载失败,改变状态为等待重新连接
                        offlineDownloadTask.setState(ConstValue.OD_TASK_STATE_RELINK);
                        taskInfo = OfflineDownloadUtils.getTaskProgressRate(taskId);
                        taskInfo.setState(offlineDownloadTask.getState());
                        //将任务添加到等待重新连接队列中
                        OfflineDownloadTaskWait taskWait = new OfflineDownloadTaskWait();
                        taskWait.setTaskId(taskId);
                        taskWait.setTotalTime(ConstValue.RETRY_TIME_LEVEL1);
                        taskWait.setCurrentTime(0);
                        taskWait.setTimeOut(false);
                        OfflineDownloadUtils.addRetryWait(taskWait);
                    }
                }
            }
            //更新数据库
            offlineDownloadTaskBiz.update(offlineDownloadTask);
            OfflineDownloadUtils.setTaskProgressRate(taskInfo);
            
            System.out.println("ID为: " + taskId + "的任务执行完成");
        }
    }

    public void setOfflineDownloadTaskBiz(IOfflineDownloadTaskBiz offlineDownloadTaskBiz) {
        this.offlineDownloadTaskBiz = offlineDownloadTaskBiz;
    }
    public void setNetdiskAccessTokenBiz(INetdiskAccessTokenBiz netdiskAccessTokenBiz) {
        this.netdiskAccessTokenBiz = netdiskAccessTokenBiz;
    }
    public void setDownloadFileTool(DownloadFileTool downloadFileTool) {
        this.downloadFileTool = downloadFileTool;
    }
}

